#! /usr/bin/env python
from  cx_Oracle import *
import sys

db_user='plmsn'
db_pass='plmsn'
conn_str = '''%s/%s@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=%s)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=%s)))'''

class PLMSNOwnerAdmin:
	'''A administration class to manager MSN owners'''
	def __init__(self, host, database, owner):
		self.myOwner = owner
		self.myConn = connect( conn_str%(db_user, db_pass, host, database) )
		self.myCursor = self.myConn.cursor()
		
	def cleanup(self):
		self.myConn.close()
	
	def getResponse(self):
		the_response = self.myCursor.var(LONG_STRING)
		plsql_get_resp = '''declare
								s integer;
							begin
								s := dbms_pipe.receive_message(dbms_pipe.unique_session_name);
								IF s <> 0 THEN
									raise_application_error(-20000, 'Error:'||to_char(s)||' receiving on pipe');
								END IF;
								dbms_pipe.unpack_message(:response);
							end;'''	
		self.myCursor.execute( plsql_get_resp, {'response':the_response} )
		return the_response.getvalue()
	
	def sendMessage(self, receiver, msg):
		plsql_send_cmd = '''declare
								s integer;
								cvs_id number := null;
								msg_opt varchar2(64) := 'Default';
							begin
								dbms_pipe.pack_message(dbms_pipe.unique_session_name);
								dbms_pipe.pack_message(item => 'SENDMSG');
								dbms_pipe.pack_message(item => :receiver);
								dbms_pipe.pack_message(item => :msg);
								dbms_pipe.pack_message(item => cvs_id);
								dbms_pipe.pack_message(item => msg_opt);
								s := dbms_pipe.send_message(:owner);
								IF s <> 0 THEN
									raise_application_error(-20000, 'Error:'||to_char(s)||' sending on pipe');
								END IF;
							end; '''
		
		self.myCursor.execute( plsql_send_cmd, {'receiver':receiver, 'msg':msg, 'owner':self.myOwner} )
		
	def logoff(self):
		plsql_logoff_cmd = '''declare
								s integer;
							begin
								dbms_pipe.pack_message(dbms_pipe.unique_session_name);
								dbms_pipe.pack_message(item => 'LOGOFF');
								s := dbms_pipe.send_message(:owner);
								IF s <> 0 THEN
									raise_application_error(-20000, 'Error:'||to_char(s)||' sending on pipe');
								END IF;
							end; '''
							
		self.myCursor.execute( plsql_logoff_cmd, {'owner':self.myOwner} )

	def process(self, command):
		args = command.split(':')
		cmd = args[0].upper()
		if cmd == 'LOGOFF':
			self.logoff()
			return self.getResponse()
		elif cmd == 'SENDMSG':
			if len(args)<> 3:
				return 'SENDMSG:<passport>:<message>'
			else:
				self.sendMessage(args[1], args[2])
				return self.getResponse()
		else:
			return 'Unknown command:', args[0]
		

if __name__ == '__main__':
	
	if len(sys.argv) != 4:
		print sys.argv[0], '<host> <database> <msn_owner>'
		sys.exit(1)
	else:
		plmsn_mgr = PLMSNOwnerAdmin(sys.argv[1], sys.argv[2], sys.argv[3])

	#try:
	while True:
		sys.stdout.write('[' + sys.argv[3] + ']: ')
		user_cmd = sys.stdin.readline().strip()
		if user_cmd=='':
			continue		
		elif user_cmd.upper() == 'EXIT':
			break
		else:
			print plmsn_mgr.process(user_cmd)				
	
	plmsn_mgr.cleanup()
	#except:
		#plmsn_mgr.cleanup()
